/*
 * @Descripttion : 视频管理器
 * @Author       : QianFox Team
 * @Date         : 2022-04-22 15:42:26
 * @LastEditors  : QianFox Team
 * @LastEditTime : 2024-08-07 09:27:33
 */

import { _typeOf } from './common/utils';
import { Manager } from './manager';
import { observer } from './common/observer';
import { pagination } from './pagination';
import { loading, closeLoading } from './loading';
import { message } from './message';
import { dialog } from './dialog';
import { _verificationIsObject, _verificationUrl } from './common/verification';

function VideoManager() {
    Manager.call(this);
    // 常量
    this.className = 'videos-manager';
    this.tabsId = 'videosManagerTabs';
    this.title = '<strong>添加视频</strong><span>(选择所需视频)</span>';
    // class 类
    this.HANDLE = `.${this.className} .video-list .video`;
    this.CONTAINER = `.${this.className}`;
    this.HANDLE_TELETE = `.${this.className} .video-list .video i`;
    this.WEBURL_INPUT = '.foxui-videos-manager__network-video .video-header input';
    this.HANDLE_LOCAL_SEARCH = '.foxui-videos-manager__choose-video .search-input button.search';
    this.HANDLE_LOCAL_UPLOAD = '.foxui-videos-manager__choose-video .add-video-btn button';
    this.UPLOAD_INPUT = '.foxui-videos-manager__choose-video .add-video-btn input';
    this.HANDLE_PREVIEW = '.foxui-videos-manager__network-video .video-header button.preview';
    this.VIDEO_LIST = '.foxui-videos-manager__choose-video .video-list .foxui-row';
    this.START_DATE_CLEAR_BTN = `.${this.className} .search-start-date .foxui-suffix-clear`;
    this.END_DATE_CLEAR_BTN = `.${this.className} .search-end-date .foxui-suffix-clear`;
    // 数据
    this.videoList = [];
    this.total = 0;
    this.currentPage = 1;
    this.startDate = '';
    this.endDate = '';
    this.choosedUrl = '';
    this.choosedId = '';
    this.choosedImgUrl = '';
    this.choosedDuration = '';
    this.choosedTitle = '';
    this.paginationOption = {
        type: 'solid',
        size: 'small',
        pageSize: 10,
        pageNum: 9,
        pageSizeList: [10, 20, 30, 50, 100],
        isShowJump: true,
        isShowTotal: true,
        isShowSize: true,
    };
    this.limitSize = ''; // 限制视频大小
}

Object.setPrototypeOf(VideoManager.prototype, Manager.prototype);

VideoManager.prototype._init = function () {
    this._addCustomer();
    this._bindMouseForVideo();
    this._bindDeleteVideo();
    this._bindSearch();
    this._bindUpload();
    this._bindPreviewVideo();
};

VideoManager.prototype._contentHtml = function () {
    return [
        `<div class="foxui-tabs foxui-type-line" id="${this.tabsId}">`,
        '<div class="foxui-tabs-header">',
        '<div class="foxui-tabs-item is-active">本地视频</div>',
        '<div class="foxui-tabs-item">网络视频</div>',
        '</div>',
        '<div class="foxui-tabs-content">',
        `<div class="foxui-tabs-pane">${this._chooseVideoHtml()}</div>`,
        `<div class="foxui-tabs-pane">${this._webVideoHtml()}</div>`,
        '</div>',
        '</div>',
    ].join('');
};

VideoManager.prototype._chooseVideoHtml = function () {
    return [
        '<div class="foxui-videos-manager__body foxui-videos-manager__choose-video">',
        '<div class="video-content">',
        // header
        '<div class="video-header">',
        '<div class="add-video-btn">',
        '<input type="file" accept="video/*" style="display:none"/>',
        '<button class="foxui-size-small foxui-solid-primary">',
        '<i class="foxui-icon-jiahao-o"></i>',
        '<span>添加视频</span>',
        '</button>',
        `<span class="info">${this.limitSize ? '大小不要超过' + this.limitSize + 'M' : ''}</span>`,
        '</div>',
        '<div class="search-input">',
        '<div class="foxui-picker foxui-date-picker search-start-date">',
        '<div class="foxui-picker-handle foxui-input-prefix">',
        `<input class="foxui-size-small" readonly="readonly" placeholder="请选择日期" value="${
            this.startDate || ''
        }" />`,
        '<i class="foxui-icon-rili-o foxui-prefix-icon"></i>',
        '<i class="foxui-icon-cuowu-o foxui-suffix-icon foxui-suffix-clear"></i>',
        '</div>',
        '</div>',
        '<div class="horizontal-line"></div>',
        '<div class="foxui-picker foxui-date-picker search-end-date">',
        '<div class="foxui-picker-handle foxui-input-prefix">',
        `<input class="foxui-size-small" readonly="readonly" placeholder="请选择日期" value="${
            this.endDate || ''
        }" />`,
        '<i class="foxui-icon-rili-o foxui-prefix-icon"></i>',
        '<i class="foxui-icon-cuowu-o foxui-suffix-icon foxui-suffix-clear"></i>',
        '</div>',
        '</div>',
        '<button class="foxui-size-small foxui-solid-primary search">搜索</button>',
        '</div>',
        '</div>',
        // list
        '<div class="video-list">',
        '<div class="foxui-row foxui-gutter-4">',
        `${this._videoListHtml(this.videoList)}`,
        '</div>',
        '</div>',
        // footer
        '<div class="video-footer">',
        '<div class="pagination-box"></div>',
        '</div>',
        '</div>',
        '</div>',
    ].join('');
};

VideoManager.prototype._webVideoHtml = function () {
    return [
        '<div class="foxui-videos-manager__body foxui-videos-manager__network-video">',
        '<div class="videos-content">',
        '<div class="video-header">',
        '<div class="foxui-input-group">',
        '<label>视频地址：</label>',
        `<input class="foxui-size-small" placeholder="请在此处粘贴视频地址" value="${
            this.webUrl || ''
        }" />`,
        '<button class="foxui-size-small foxui-solid-primary preview">预览</button>',
        '</div>',
        '<p>视频仅支持mp4格式，粘贴视频地址后点击预览铵钮可观看视频</p>',
        '</div>',
        '<div class="video-preview">',
        '<div class="video-placeholder">',
        '<div class="info">',
        '<span>视频预览区</span>',
        '</div>',
        '</div>',
        '</div>',
        '</div>',
        '</div>',
    ].join('');
};

VideoManager.prototype._videoListHtml = function () {
    let htmlArr = [];
    this.videoList.forEach(item => {
        htmlArr.push(
            [
                '<div class="column-5">',
                `<div class="video" data-src="${item.videoSrc}" data-id="${item.id}" data-title="${
                    item.name ? item.name.split('.')[0] : ''
                }">`,
                `<img src="${item.imgSrc}"/>`,
                '<i class="foxui-icon-cuowu-f"></i>',
                `<span class="duration">${item.duration || ''}</span>`,
                '</div>',
                '<div class="text">',
                `<span>${item.name}</span>`,
                ' </div>',
                '</div>',
            ].join('')
        );
    });
    return htmlArr.join('');
};

/**
 * @description: 添加分页
 * @param {*}
 * @return {*}
 * @Date: 2022-04-24 16:18:33
 */
VideoManager.prototype._addPagination = function () {
    let that = this;
    pagination(
        {
            el: `.${this.className} .pagination-box`,
            currentPage: this.currentPage,
            total: this.total,
            onchange: function ({ currentPage, pageSize }) {
                loading({
                    el: `.${that.className}`,
                    text: '视频加载中...',
                });
                // 保存数据
                that.currentPage = currentPage;
                that.paginationOption.pageSize = pageSize;
                // 接收数据
                that._ajax(
                    that._uploadData({
                        handle: 'get',
                    })
                );
            },
        },
        this.paginationOption
    );
};

/**
 * @description: 绑定鼠标事件(鼠标移入、鼠标移出、鼠标点击->选中)
 * @param {*}
 * @return {*}
 * @Date: 2022-04-24 16:10:45
 */
VideoManager.prototype._bindMouseForVideo = function () {
    let that = this;
    $(document).on('mouseover', this.HANDLE, function () {
        let $this = $(this),
            isActive = $this.is('.is-active');
        if (!isActive) {
            $this.find('i').fadeIn(100);
        }
    });

    $(document).on('mouseleave', this.HANDLE, function () {
        let $this = $(this),
            isActive = $this.is('.is-active');
        if (!isActive) {
            $this.find('i').fadeOut(100);
        }
    });

    $(document).on('click', this.HANDLE, function () {
        let $this = $(this),
            $img = $this.find('img'),
            $duration = $this.find('.duration'),
            isActive = $this.is('.is-active');
        if (isActive) {
            $this.removeClass('is-active');
            that.choosedUrl = '';
            that.choosedId = '';
            that.choosedImgUrl = '';
            that.choosedTitle = '';
            that.choosedDuration = '';
            $this.find('i').fadeIn(100);
        } else {
            $this.closest(that.CONTAINER).find('.video-list .video').removeClass('is-active');
            $this.addClass('is-active');
            that.choosedUrl = $this.attr('data-src');
            that.choosedId = $this.attr('data-id');
            that.choosedTitle = $this.attr('data-title');
            that.choosedImgUrl = $img.attr('src');
            that.choosedDuration = $duration.text();
            $this.find('i').fadeOut(100);
        }
    });
};

/**
 * @description: 绑定删除图片
 * @param {*}
 * @return {*}
 * @Date: 2022-04-24 16:34:59
 */
VideoManager.prototype._bindDeleteVideo = function () {
    let that = this;
    $(document).on('click', this.HANDLE_TELETE, function (event) {
        let handle = this;
        event.stopPropagation();
        dialog({
            title: '删除',
            content: '您确定要删除视频吗',
            cancelText: '取消',
            confirmText: '删除',
            buttonType: 'danger',
            confirm: function (callback) {
                // 收集数据
                let $video = $(handle).closest('.video'),
                    deleteUrl = $video.attr('data-src'),
                    deleteId = $video.attr('data-id');
                // 关闭对话框
                callback();
                // 添加加载层
                loading({
                    el: `.${that.className}`,
                    text: '视频正在删除中...',
                });
                // 接收数据
                that._ajax(
                    that._uploadData({
                        handle: 'deleteVideo',
                        deleteUrl,
                        deleteId,
                    })
                );
            },
        });
    });
};

/**
 * @description: 绑定按日期搜索
 * @param {*}
 * @return {*}
 * @Date: 2022-04-24 16:41:04
 */
VideoManager.prototype._bindSearch = function () {
    let that = this;
    $(document).on('click', this.HANDLE_LOCAL_SEARCH, function () {
        // 数据收集
        let $this = $(this),
            startDate = $this.siblings('.search-start-date').find('input').val(),
            endDate = $this.siblings('.search-end-date').find('input').val();
        // 保存数据
        that.startDate = startDate;
        that.endDate = endDate;
        that.currentPage = 1;
        // 添加加载层
        loading({
            el: `.${that.className}`,
            text: '视频加载中...',
        });
        // 接收数据
        that._ajax(
            that._uploadData({
                handle: 'get',
            })
        );
    });

    $(document).on('click', this.START_DATE_CLEAR_BTN, function () {
        that.startDate = '';
    });

    $(document).on('click', this.END_DATE_CLEAR_BTN, function () {
        that.endDate = '';
    });
};

/**
 * @description: 绑定上传视频
 * @param {*}
 * @return {*}
 * @Date: 2022-04-24 16:48:33
 */
VideoManager.prototype._bindUpload = function () {
    let that = this;
    $(document).on('click', this.HANDLE_LOCAL_UPLOAD, function () {
        let $input = $(this).siblings('input[type="file"]');
        $input.val('');
        $input[0].click();
    });

    $(document).on('change', this.UPLOAD_INPUT, function (event) {
        // 添加进度条
        that._addProgress('视频');
        let file = event.target.files[0];
        if (file.size <= that.limitSize * 1024 * 1024) {
            if (file.type.split('/')[0] == 'video') {
                that._upload(file);
            } else {
                // 关闭进度条
                if (that.progress) that._removeProgress();
                message({
                    text: '只能上传视频文件',
                    type: 'danger',
                });
            }
        } else {
            // 关闭进度条
            if (that.progress) that._removeProgress();
            message({
                text: `上传视频不能大于${that.limitSize}M`,
                type: 'danger',
            });
        }
    });
};

/**
 * @description: 上传文件
 * @param {*} file
 * @return {*}
 * @Date: 2022-04-24 16:55:52
 */
VideoManager.prototype._upload = function (file) {
    // 保存数据
    this.currentPage = 1;
    // 请求
    this._ajax(
        this._uploadData({
            handle: 'upload',
            file,
        })
    );
};

VideoManager.prototype._uploadData = function ({ handle, deleteUrl, deleteId, file }) {
    let uploadData = { handle };

    if (handle === 'get') {
        uploadData.startDate = this.startDate;
        uploadData.endDate = this.endDate;
        uploadData.currentPage = this.currentPage;
        uploadData.pageSize = this.paginationOption.pageSize;
    } else if (handle === 'upload') {
        let formData = new FormData();
        formData.append('file', file);
        formData.append('pageSize', this.paginationOption.pageSize);
        formData.append('currentPage', this.currentPage);
        formData.append('event', 'change');
        formData.append('handle', 'upload');
        uploadData.formData = formData;
    } else if (handle === 'deleteVideo') {
        uploadData.startDate = this.startDate;
        uploadData.endDate = this.endDate;
        uploadData.currentPage = this.currentPage;
        uploadData.pageSize = this.paginationOption.pageSize;
        uploadData.id = deleteId;
        uploadData.url = deleteUrl;
    }
    return uploadData;
};

/**
 * @description: 绑定预览视频
 * @param {*}
 * @return {*}
 * @Date: 2022-04-24 17:14:48
 */
VideoManager.prototype._bindPreviewVideo = function () {
    let that = this;
    $(document).on('click', this.HANDLE_PREVIEW, function () {
        let $this = $(this),
            videoUrl = $this.siblings('input').val();
        if (_verificationUrl(videoUrl)) {
            $this
                .closest(that.CONTAINER)
                .find('.video-preview')
                .empty()
                .append(`<video src="${videoUrl}" controls="controls"></video>`);
        } else {
            message({
                text: '请先填入正确的视频地址',
                type: 'danger',
            });
        }
    });
};

/**
 * @description: 点击确定后，执行函数
 * @param {*} callback
 * @return {*}
 * @Date: 2022-04-22 17:21:20
 */
VideoManager.prototype._confirm = function (callback) {
    // 判断是选择视频，还是网络视频
    if (this.tabsIndex < 1) {
        if (this.choosedUrl) {
            // 发布消息(内部)
            observer._publiced('videosManager', {
                choosedUrl: this.choosedUrl,
                choosedId: this.choosedId,
                choosedTitle: this.choosedTitle,
                choosedImgUrl: this.choosedImgUrl,
                choosedDuration: this.choosedDuration,
                target: this.target,
            });
            // 发布消息
            let subid = $(this.target).closest('[data-subid]').attr('data-subid');
            if (subid)
                observer._publiced(
                    'custom',
                    {
                        choosedUrl: this.choosedUrl,
                        choosedId: this.choosedId,
                        choosedTitle: this.choosedTitle,
                        choosedImgUrl: this.choosedImgUrl,
                        choosedDuration: this.choosedDuration,
                    },
                    subid,
                    'confirm'
                );
            // 修复第二次打开时，数据还存在
            this.choosedUrl = '';
            this.choosedId = '';
            this.choosedImgUrl = '';
            this.choosedTitle = '';
            this.choosedDuration = '';
            // 关闭对话框
            callback();
        } else {
            message({
                text: '请先选择视频',
                type: 'warning',
            });
        }
    } else {
        let webUrl = $(this.WEBURL_INPUT).val();
        if (_verificationUrl(webUrl)) {
            // 发布消息(内部)
            observer._publiced('videosManager', { choosedUrl: webUrl, target: this.target });
            // 发布消息
            let subid = $(this.target).closest('[data-subid]').attr('data-subid');
            if (subid) observer._publiced('custom', { choosedUrl: webUrl }, subid, 'confirm');
            // 关闭对话框
            callback();
        } else {
            message({
                text: '请输入正确的视频地址',
                type: 'warning',
            });
        }
    }
};

VideoManager.prototype._ajax = function (data, event) {
    let that = this,
        params = {
            type: 'post',
            url: this.url,
            async: event === 'init' ? false : true,
            xhr: function () {
                let xhr = new XMLHttpRequest();
                xhr.upload.addEventListener(
                    'progress',
                    function (event) {
                        if (event.lengthComputable) {
                            let percentComplete = (event.loaded / event.total) * 100;
                            if (that.progress) {
                                that.progress.update(parseInt(percentComplete));
                            }
                        }
                    },
                    false
                );
                return xhr;
            },
            success: function (res) {
                // 判断是不是初始化
                if (event === 'init') {
                    if (res.code === 1) {
                        const {
                            videoList,
                            currentPage,
                            startDate,
                            endDate,
                            pageSize,
                            total,
                            limitSize,
                        } = res.data;
                        videoList && videoList.length > 0 && (that.videoList = videoList);
                        currentPage && (that.currentPage = currentPage);
                        pageSize && (that.paginationOption.pageSize = pageSize);
                        that.startDate = startDate;
                        that.endDate = endDate;
                        total && (that.total = total);
                        parseFloat(limitSize) && (that.limitSize = parseFloat(limitSize));
                    } else {
                        message({
                            text: res.msg,
                            type: 'danger',
                        });
                    }
                    // 关闭加载层
                    closeLoading();
                } else {
                    // 如不是初始化，更新
                    if (res.code === 1) {
                        that._update(res.data);
                    } else {
                        message({
                            text: res.msg,
                            type: 'danger',
                        });
                    }
                    // 关闭加载层
                    closeLoading(`.${that.className}`);
                    // 关闭进度条
                    if (that.progress) that._removeProgress();
                }
            },
            error: function (xhr, status, error) {
                // 关闭加载层
                closeLoading(`.${that.className}`);
                // 关闭进度条
                if (that.progress) that._removeProgress();
                message({
                    text: '视频上传失败',
                    type: 'danger',
                });
            },
        };
    // 判断是不是上传文件
    if (data.handle === 'upload') {
        params.data = data.formData;
        params.contentType = false;
        params.processData = false;
        // 前面已追加了 event 到 formData
    } else {
        // 添加 event
        data.event = event || 'change';
        params.data = data;
    }
    // 添加加载层
    if (event === 'init') loading();
    // 发起请求
    $.ajax(params);
};

VideoManager.prototype._update = function (data) {
    let $videoList = $(this.VIDEO_LIST);
    const { currentPage, startDate, endDate, pageSize, total, handle, videoList } = data;
    // 保存存数据
    this.videoList = videoList;
    this.startDate = startDate;
    this.endDate = endDate;
    this.currentPage = currentPage;
    this.paginationOption.pageSize = pageSize;
    this.total = total;
    // 更新
    $videoList.empty().append(this._videoListHtml());
    this._addPagination();
    // 添加提示
    if (handle === 'deleteVideo') {
        message({
            text: '视频删除成功',
            type: 'success',
        });
    } else if (handle === 'upload') {
        message({
            text: '视频上传成功',
            type: 'success',
        });
    }
};

/**
 * @description: 添加订阅者(内部)
 * @param {*} callback
 * @return {*}
 * @Date: 2022-04-22 17:15:02
 */
VideoManager.prototype._onConfirm = function (callback) {
    observer._subscribe('videosManager', callback);
};

/**
 * @description: 添加订阅者
 * @param {*} subid
 * @param {*} callback
 * @return {*}
 * @Date: 2024-08-06 17:35:29
 */
VideoManager.prototype.onConfirm = function (subid, callback) {
    if (subid && _typeOf(callback) === 'function') {
        observer._subscribe('custom', callback, subid, 'confirm');
    }
};

/**
 * @description: 取消订阅(内部)
 * @param {*} callback
 * @return {*}
 * @Date: 2022-04-22 17:15:47
 */
VideoManager.prototype._unConfirm = function (callback) {
    observer._unsubscribe('videosManager', callback);
};

/**
 * @description: 取消订阅
 * @param {*} subid
 * @return {*}
 * @Date: 2024-08-06 17:34:10
 */
VideoManager.prototype.unConfirm = function (subid) {
    if (subid) observer._unsubscribe('custom', null, subid, 'confirm');
};

VideoManager.prototype.init = function ({ paginationOption, url }) {
    // 校验 paginationOption
    paginationOption && _verificationIsObject(paginationOption, true, 'paginationOption');
    // 保存
    paginationOption && (this.paginationOption = paginationOption);
    this.url = url;
};

let videoManager = new VideoManager();

export { videoManager };
